<template>
  <div class="form">
    <el-form ref="form" label-width="80px">
      <el-form-item label="经度">
        <el-input v-model.number="lng"></el-input>
      </el-form-item>
      <el-form-item label="纬度">
        <el-input v-model.number="lat"></el-input>
      </el-form-item>
      <el-form-item label="高度">
        <el-input v-model.number="height"></el-input>
      </el-form-item>
      <el-form-item label="偏航角">
        <el-input v-model.number="heading"></el-input>
      </el-form-item>
      <el-form-item label="俯仰角">
        <el-input v-model.number="pitch"></el-input>
      </el-form-item>
      <el-form-item label="翻转角">
        <el-input v-model.number="roll"></el-input>
      </el-form-item>
      <el-form-item label="缩放">
        <el-input v-model.number="scale"></el-input>
      </el-form-item>
      <el-form-item label="模型类型">
        <el-select v-model="modelType" placeholder="请选择">
          <el-option
            v-for="item in modelTypeOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item v-if="modelType === 'glb'" label="模型文件">
        <el-upload :on-change="handleChangeFile" :auto-upload="false" class="upload-demo" action="*">
          <el-button size="small" type="default">点击上传</el-button>
        </el-upload>
        <div style="color:#999;font-size:12px;text-align:left;line-height:16px;">模型文件格式：glb/gltf</div>
      </el-form-item>
      <el-form-item v-if="modelType === '3dtiles'" label="模型地址">
        <el-input v-model="threedtilesUrl"></el-input>
      </el-form-item>
      <div style="padding-bottom:16px;text-align:right">
        <el-button @click="loadModel" size="small" type="primary">载入模型</el-button>
        <el-button @click="handleClear" size="small">清除模型</el-button>
      </div>
    </el-form>
  </div>
</template>

<script>
import * as Cesium from 'cesium'
import cesiumConfig from '@/components/dogeo/cesium/config.js'
import model from '@/components/dogeo/cesium/model.js'

export default {
  name: 'tool-locate',

  props: {
    viewer: {
      type: Object,
      default () {
        return null
      }
    }
  },

  data () {
    return {
      lng: cesiumConfig.destination.lng,
      lat: cesiumConfig.destination.lat,
      height: cesiumConfig.destination.height,
      heading: cesiumConfig.orientation.heading,
      pitch: cesiumConfig.orientation.pitch,
      roll: cesiumConfig.orientation.roll,
      scale: 1,
      modelType: 'glb',
      modelTypeOptions: [
        {label: 'GLB/GLTF', value: 'glb'},
        {label: '3DTiles', value: '3dtiles'}
      ],
      file: null,
      threedtilesUrl: ''
    }
  },

  methods: {
    handleChangeFile (file, fileslist) {
      if (fileslist.length > 1) {
        fileslist.shift()
      }
      this.file = file.raw
    },
    loadModel () {
      // 3dtiles
      if (this.modelType === '3dtiles') {
        if (!this.threedtilesUrl) {
          this.$message({
            type: 'error',
            message: '未输入模型地址'
          })
          return true
        }
        this.loadThreeDTiles()
        return true
      }
      if (!this.file) {
        this.$message({
          type: 'error',
          message: '未上传模型'
        })
        return true
      }
      if (!/\.gl/.test(this.file.name)) {
        this.$message({
          type: 'error',
          message: '请上传glb/gltf模型'
        })
        return true
      }
      this.fileToBase64(this.file).then(url => {
        this.loadModelResult(url, Cesium.Cartesian3.fromDegrees(this.lng, this.lat, this.height || 100))
      })
    },
    loadModelResult (url, cartesian3) {
      let viewer = this.viewer
      var scene = viewer.scene
      if (this.model) {
        scene.primitives.remove(this.model)
        this.model = null
      }
      const loading = this.$loading({
        lock: true,
        text: 'Loading',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      })
      // gltf数据加载位置
      var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(cartesian3)
      try {
        var model = scene.primitives.add(Cesium.Model.fromGltf({
          url: url, // gltf文件的URL
          modelMatrix: modelMatrix,
          scale: 1,   //放大倍数
        }))
        model.readyPromise.then(() => {
          let form = {
            heading: this.heading, // -45
            pitch: this.pitch,
            roll: this.roll,
            scale: parseFloat(this.scale) || 1,
            offsetX: 0,
            offsetY: 0,
            offsetZ: 0,
          }
          // 确定矩阵变化的原点
          let origin = cartesian3 // Cesium.Cartesian3.fromDegrees(form.lon, form.lat, form.height);
          let transform = Cesium.Transforms.eastNorthUpToFixedFrame(origin);
          // 缩放
          let scale = Cesium.Matrix4.fromScale(new Cesium.Cartesian3(form.scale, form.scale, form.scale));
          Cesium.Matrix4.multiply(transform, scale, transform);
          // 平移
          let translation = Cesium.Matrix4.fromTranslation(new Cesium.Cartesian3(form.offsetX, form.offsetY, form.offsetZ));
          Cesium.Matrix4.multiply(transform, translation, transform);
          // 旋转
          let heading = Cesium.Math.toRadians(form.heading);
          let pitch = Cesium.Math.toRadians(form.pitch);
          let roll = Cesium.Math.toRadians(form.roll);
          let hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
          let matrix3 = Cesium.Matrix3.fromHeadingPitchRoll(hpr);
          let rotation = Cesium.Matrix4.fromRotationTranslation(matrix3);
          Cesium.Matrix4.multiply(transform, rotation, transform);
          // 设置
          model.modelMatrix = transform;
          this.model = model
        })
      } catch (error) {
        console.log(error)
      } finally {
        setTimeout(() => {
          loading.close()
        }, 500)
      }
      viewer.camera.flyTo({
        destination: Cesium.Cartesian3.fromDegrees(this.lng, this.lat, 1000),
        orientation: {
          heading: Cesium.Math.toRadians(0), // 水平偏角，默认正北 0
          pitch: Cesium.Math.toRadians(-90), // 俯视角，默认-90，垂直向下
          roll: 0, // 旋转角
        }
      })
    },
    fileToBase64(file) {
      return new Promise((resolve, reject) => {
        const reader = new FileReader()
        reader.readAsDataURL(file)
        reader.onload = () => resolve(reader.result)
        reader.onerror = (error) => reject(error)
      })
    },
    // 加载3dtiles
    loadThreeDTiles () {
      model.loadThreeDTiles(this.viewer, this.threedtilesUrl, {
        destination: {
          lng: this.lng,
          lat: this.lat,
          height: this.height
        }
      })
      this.viewer.camera.flyTo({
        destination: Cesium.Cartesian3.fromDegrees(this.lng, this.lat, this.height),
        orientation: {
          heading: Cesium.Math.toRadians(this.heading), // 水平偏角，默认正北 0
          pitch: Cesium.Math.toRadians(this.pitch), // 俯视角，默认-90，垂直向下
          roll: this.roll // 旋转角
        }
      })
    },
    // 清除
    handleClear () {
      if (!this.viewer) {
        return true
      }
      if (!this.model) {
        return true
      }
      this.viewer.scene.primitives.remove(this.model)
    }
  }
}
</script>

<style lang="less">
.upload-demo {
  text-align: left;
}
</style>